import pygame
import time
from .game_board import GameBoard
from .data.database import Database

class GameState:
    """游戏状态枚举"""
    MENU = 0
    LEVEL_SELECT = 1
    PLAYING = 2
    PAUSED = 3
    GAME_OVER = 4
    LEVEL_COMPLETE = 5
    LOGIN = 6
    LEADERBOARD = 7

class GameLogic:
    """游戏逻辑类，管理游戏流程和状态"""
    
    def __init__(self, screen_width, screen_height):
        """
        初始化游戏逻辑
        
        参数:
            screen_width: 屏幕宽度
            screen_height: 屏幕高度
        """
        self.screen_width = screen_width
        self.screen_height = screen_height
        
        # 游戏状态
        self.state = GameState.MENU
        self.current_level = 1
        self.player_id = None
        self.player_name = "玩家"
        
        # 游戏配置
        self.level_data = {}
        self.time_limit = 60  # 默认时间限制（秒）
        self.target_score = 1000  # 默认目标分数
        
        # 游戏计时
        self.start_time = 0
        self.elapsed_time = 0
        self.time_left = 0
        
        # 游戏板
        self.board = None
        
        # 数据库连接
        self.db = Database()
        
    def initialize(self):
        """初始化游戏"""
        # 连接数据库
        self.db.connect()
        
        # 加载关卡数据
        self._load_level_data()
    
    def _load_level_data(self):
        """从数据库加载关卡数据"""
        if not self.db.connection:
            print("数据库未连接，使用默认关卡配置")
            self.level_data = {
                1: {"difficulty": 1, "target_score": 1000, "time_limit": 60, "layout": '{"size": 8, "types": 5}'},
                2: {"difficulty": 2, "target_score": 2000, "time_limit": 60, "layout": '{"size": 8, "types": 6}'},
                3: {"difficulty": 3, "target_score": 3000, "time_limit": 45, "layout": '{"size": 9, "types": 6}'},
            }
            return
        
        try:
            levels = self.db.execute_query("SELECT * FROM level ORDER BY level_id")
            for level in levels:
                self.level_data[level['level_id']] = {
                    "difficulty": level['difficulty'],
                    "target_score": level['target_score'],
                    "time_limit": level['time_limit'],
                    "layout": level['layout']
                }
        except Exception as e:
            print(f"加载关卡数据失败: {e}")
            # 使用默认配置
            self.level_data = {
                1: {"difficulty": 1, "target_score": 1000, "time_limit": 60, "layout": '{"size": 8, "types": 5}'},
                2: {"difficulty": 2, "target_score": 2000, "time_limit": 60, "layout": '{"size": 8, "types": 6}'},
                3: {"difficulty": 3, "target_score": 3000, "time_limit": 45, "layout": '{"size": 9, "types": 6}'},
            }
            
    def start_level(self, level_id):
        """
        开始指定关卡
        
        参数:
            level_id: 关卡ID
        """
        self.current_level = level_id
        
        # 获取关卡配置
        level_config = self.level_data.get(level_id, {
            "difficulty": 1, 
            "target_score": 1000, 
            "time_limit": 60, 
            "layout": '{"size": 8, "types": 5}'
        })
        
        # 设置关卡参数
        self.target_score = level_config["target_score"]
        self.time_limit = level_config["time_limit"]
        
        # 根据关卡配置创建游戏板
        import json
        layout = json.loads(level_config["layout"])
        size = layout.get("size", 8)
        types = layout.get("types", 5)
        
        # 计算适当的方块大小，使游戏板居中
        tile_size = min(
            (self.screen_width * 0.8) // size,
            (self.screen_height * 0.8) // size
        )
        
        # 创建游戏板
        self.board = GameBoard(size, size, tile_size, types)
        
        # 初始化游戏状态
        self.state = GameState.PLAYING
        self.start_time = time.time()
        self.elapsed_time = 0
        self.time_left = self.time_limit
        
    def update(self):
        """更新游戏状态"""
        if self.state == GameState.PLAYING:
            # 更新游戏板
            if self.board:
                self.board.update()
                
                # 更新时间
                self.elapsed_time = time.time() - self.start_time
                self.time_left = max(0, self.time_limit - self.elapsed_time)
                
                # 检查游戏是否结束
                if self.time_left <= 0:
                    self.state = GameState.GAME_OVER
                    self._save_score()
                
                # 检查是否达成目标
                if self.board.score >= self.target_score:
                    self.state = GameState.LEVEL_COMPLETE
                    self._save_score()
                    
                # 检查是否无法继续移动
                if self.board.is_game_over():
                    self.state = GameState.GAME_OVER
                    self._save_score()
                    
    def handle_event(self, event):
        """
        处理游戏事件
        
        参数:
            event: pygame事件对象
        
        返回值:
            bool: 是否继续运行游戏
        """
        if event.type == pygame.QUIT:
            return False
            
        if event.type == pygame.KEYDOWN:
            # ESC键返回菜单
            if event.key == pygame.K_ESCAPE:
                if self.state == GameState.PLAYING:
                    self.state = GameState.PAUSED
                elif self.state == GameState.PAUSED:
                    self.state = GameState.PLAYING
                    self.start_time = time.time() - self.elapsed_time  # 调整开始时间
                else:
                    self.state = GameState.MENU
                    
            # 空格键在不同状态间切换
            if event.key == pygame.K_SPACE:
                if self.state == GameState.GAME_OVER or self.state == GameState.LEVEL_COMPLETE:
                    self.state = GameState.LEVEL_SELECT
                elif self.state == GameState.PAUSED:
                    self.state = GameState.PLAYING
                    self.start_time = time.time() - self.elapsed_time  # 调整开始时间
                    
        # 处理鼠标点击
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键点击
                if self.state == GameState.PLAYING and self.board:
                    # 计算游戏板的位置偏移，使其居中
                    offset_x = (self.screen_width - self.board.width) // 2
                    offset_y = (self.screen_height - self.board.height) // 2
                    
                    # 处理游戏板上的点击
                    self.board.handle_click(event.pos[0], event.pos[1], offset_x, offset_y)
                    
        return True
                    
    def draw(self, screen):
        """
        绘制游戏界面
        
        参数:
            screen: pygame的Surface对象，用于绘制
        """
        # 清空屏幕
        screen.fill((30, 30, 40))
        
        if self.state == GameState.PLAYING or self.state == GameState.PAUSED:
            # 绘制游戏板
            if self.board:
                # 计算居中位置
                offset_x = (self.screen_width - self.board.width) // 2
                offset_y = (self.screen_height - self.board.height) // 2
                
                self.board.draw(screen, offset_x, offset_y)
                
                # 绘制UI信息
                self._draw_game_ui(screen)
                
                # 如果游戏暂停，绘制暂停信息
                if self.state == GameState.PAUSED:
                    self._draw_pause_screen(screen)
                    
        elif self.state == GameState.GAME_OVER:
            self._draw_game_over_screen(screen)
            
        elif self.state == GameState.LEVEL_COMPLETE:
            self._draw_level_complete_screen(screen)
            
    def _draw_game_ui(self, screen):
        """绘制游戏UI"""
        font = pygame.font.SysFont('SimHei', 28)
        
        # 绘制分数
        score_text = font.render(f"分数: {self.board.score}/{self.target_score}", True, (255, 255, 255))
        screen.blit(score_text, (20, 20))
        
        # 绘制时间
        minutes = int(self.time_left) // 60
        seconds = int(self.time_left) % 60
        time_text = font.render(f"时间: {minutes:02d}:{seconds:02d}", True, (255, 255, 255))
        screen.blit(time_text, (20, 60))
        
        # 绘制关卡信息
        level_text = font.render(f"关卡: {self.current_level}", True, (255, 255, 255))
        screen.blit(level_text, (20, 100))
        
        # 绘制操作次数
        moves_text = font.render(f"移动次数: {self.board.moves}", True, (255, 255, 255))
        screen.blit(moves_text, (20, 140))
        
    def _draw_pause_screen(self, screen):
        """绘制暂停屏幕"""
        # 创建半透明的黑色覆盖层
        overlay = pygame.Surface((self.screen_width, self.screen_height), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 绘制暂停文本
        font = pygame.font.SysFont('SimHei', 48)
        text = font.render("游戏暂停", True, (255, 255, 255))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 - 50))
        screen.blit(text, text_rect)
        
        # 绘制继续提示
        font = pygame.font.SysFont('SimHei', 28)
        text = font.render("按空格键继续游戏", True, (200, 200, 200))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 + 30))
        screen.blit(text, text_rect)
        
    def _draw_game_over_screen(self, screen):
        """绘制游戏结束屏幕"""
        # 创建半透明的黑色覆盖层
        overlay = pygame.Surface((self.screen_width, self.screen_height), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        screen.blit(overlay, (0, 0))
        
        # 绘制游戏结束文本
        font = pygame.font.SysFont('SimHei', 48)
        text = font.render("游戏结束", True, (255, 50, 50))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 - 100))
        screen.blit(text, text_rect)
        
        # 绘制分数
        font = pygame.font.SysFont('SimHei', 36)
        text = font.render(f"最终分数: {self.board.score}", True, (255, 255, 255))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 - 20))
        screen.blit(text, text_rect)
        
        # 绘制继续提示
        font = pygame.font.SysFont('SimHei', 28)
        text = font.render("按空格键返回关卡选择", True, (200, 200, 200))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 + 60))
        screen.blit(text, text_rect)
        
    def _draw_level_complete_screen(self, screen):
        """绘制关卡完成屏幕"""
        # 创建半透明的黑色覆盖层
        overlay = pygame.Surface((self.screen_width, self.screen_height), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        screen.blit(overlay, (0, 0))
        
        # 绘制关卡完成文本
        font = pygame.font.SysFont('SimHei', 48)
        text = font.render("关卡完成！", True, (50, 255, 50))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 - 100))
        screen.blit(text, text_rect)
        
        # 绘制分数
        font = pygame.font.SysFont('SimHei', 36)
        text = font.render(f"最终分数: {self.board.score}", True, (255, 255, 255))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 - 20))
        screen.blit(text, text_rect)
        
        # 绘制移动次数和时间
        font = pygame.font.SysFont('SimHei', 28)
        text = font.render(f"移动次数: {self.board.moves}  剩余时间: {int(self.time_left)}秒", True, (200, 200, 200))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 + 20))
        screen.blit(text, text_rect)
        
        # 绘制继续提示
        text = font.render("按空格键继续", True, (200, 200, 200))
        text_rect = text.get_rect(center=(self.screen_width//2, self.screen_height//2 + 80))
        screen.blit(text, text_rect)
        
    def _save_score(self):
        """保存游戏分数到数据库"""
        if not self.db.connection or self.player_id is None:
            print("未登录或数据库未连接，无法保存分数")
            return
            
        try:
            query = """
            INSERT INTO score (player_id, level_id, score)
            VALUES (%s, %s, %s)
            """
            self.db.execute_update(query, (self.player_id, self.current_level, self.board.score))
            print(f"分数保存成功: 玩家{self.player_id}，关卡{self.current_level}，分数{self.board.score}")
        except Exception as e:
            print(f"保存分数失败: {e}")
            
    def login_player(self, username, password):
        """
        玩家登录
        
        参数:
            username: 用户名
            password: 密码
            
        返回值:
            bool: 是否登录成功
        """
        if not self.db.connection:
            print("数据库未连接，无法登录")
            return False
            
        try:
            query = "SELECT player_id FROM player WHERE username = %s AND password = %s"
            result = self.db.execute_query(query, (username, password))
            
            if result:
                self.player_id = result[0]['player_id']
                self.player_name = username
                print(f"登录成功: {username}")
                return True
            else:
                print(f"登录失败: 用户名或密码错误")
                return False
        except Exception as e:
            print(f"登录失败: {e}")
            return False
            
    def register_player(self, username, password):
        """
        注册新玩家
        
        参数:
            username: 用户名
            password: 密码
            
        返回值:
            bool: 是否注册成功
        """
        if not self.db.connection:
            print("数据库未连接，无法注册")
            return False
            
        try:
            # 检查用户名是否已存在
            query = "SELECT player_id FROM player WHERE username = %s"
            result = self.db.execute_query(query, (username,))
            
            if result:
                print(f"注册失败: 用户名 {username} 已存在")
                return False
                
            # 插入新用户
            query = "INSERT INTO player (username, password) VALUES (%s, %s)"
            self.db.execute_update(query, (username, password))
            
            # 获取新插入的用户ID
            query = "SELECT player_id FROM player WHERE username = %s"
            result = self.db.execute_query(query, (username,))
            
            if result:
                self.player_id = result[0]['player_id']
                self.player_name = username
                print(f"注册成功: {username}")
                return True
            else:
                print(f"注册失败: 未知错误")
                return False
        except Exception as e:
            print(f"注册失败: {e}")
            return False
            
    def get_high_scores(self, level_id=None, limit=10):
        """
        获取排行榜数据
        
        参数:
            level_id: 关卡ID，如果为None则获取所有关卡
            limit: 返回的最大记录数
            
        返回值:
            list: 排行榜数据列表
        """
        if not self.db.connection:
            print("数据库未连接，无法获取排行榜")
            return []
            
        try:
            if level_id is not None:
                query = """
                SELECT s.score_id, p.username, s.level_id, s.score, s.played_at
                FROM score s
                JOIN player p ON s.player_id = p.player_id
                WHERE s.level_id = %s
                ORDER BY s.score DESC
                LIMIT %s
                """
                result = self.db.execute_query(query, (level_id, limit))
            else:
                query = """
                SELECT s.score_id, p.username, s.level_id, s.score, s.played_at
                FROM score s
                JOIN player p ON s.player_id = p.player_id
                ORDER BY s.score DESC
                LIMIT %s
                """
                result = self.db.execute_query(query, (limit,))
                
            return result
        except Exception as e:
            print(f"获取排行榜失败: {e}")
            return [] 